package at.theengine.android.gs4android;

import java.io.IOException;
import java.io.InputStream;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
import at.theengine.android.botstorage.*;
import at.theengine.android.botstorage.gsobjects.File;
import at.theengine.android.botstorage.gsobjects.GsObjects;

public class ObjectBrowser extends Activity {

	private GSDataAdapter gsd;
	private static final String tag = "GS4ANDROID";
	public static final String PREFS_NAME = "GS4ANDROID_SETTINGS";

	private SharedPreferences settings;

	private ListView lstFolders;
	private ListView lstFiles;
	private TextView tvPath;
	private ProgressDialog pdlg;

	private String[] files;
	private String[] folders;
	
	private String file;

	private ObjectBrowser ctx;

	private String path;
	private String bucket;

	// menu item ids
	private static final int MENU_RELOAD = Menu.FIRST;
	private static final int MENU_BUCKETS = Menu.FIRST + 1;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.files);

		ctx = this;
		lstFiles = (ListView) this.findViewById(R.id.lstFiles);
		lstFolders = (ListView) this.findViewById(R.id.lstFolders);
		tvPath = (TextView) this.findViewById(R.id.tvPath);

		path = "";
		bucket = getIntent().getStringArrayListExtra("PATH").get(0) + "/";

		loadObjects();

		tvPath.setText("/HOME" + "/" + bucket + path);
	}

	private boolean refreshGsd() {
		settings = getSharedPreferences(PREFS_NAME, 0);
		String key = settings.getString("gsKey", "");
		String secret = settings.getString("gsSecret","");

		if (key.equals("") || secret.equals("")) {
			Toast.makeText(this, "Google Storage Key and Secret not set!",
					Toast.LENGTH_LONG).show();
			return false;
		}

		if (gsd == null) {
			gsd = new GSDataAdapter(key, secret);
		}
		return true;
	}

	private void loadObjects(){
    	if(!refreshGsd()){ return; } 
    	
    	pdlg = ProgressDialog.show(this,"", "loading objects...", true); 
    	pdlg.show();
    	
    	class ObjectLoader extends AsyncTask<Void, String, Void> {

    		private GsObjects objects;
    		private boolean success = false;
    		private String error;
    		
    		@Override
    		protected Void doInBackground(Void... unused) {
    			int i = 0;
    			while(i < 100 && success == false){ //only for debug remove this loop
		    		try {
		    			objects = gsd.getObjectNames(bucket,path);
		    			seperateFoldersAndFiles();
		    			success = true;
		    		} catch (BotStorageException e) {
		    			success = false;
		    			//gsd = null;
		    			error = e.getMessage();
					}
		    		i++;
    			}
    			return(null);
    		}
    		
    		private void seperateFoldersAndFiles(){
    			files = new String[objects.getFiles().length];
    			for(int i = 0;i < objects.getFiles().length;i++){
    				files[i] = objects.getFiles()[i].getKey().substring(0+path.length(),objects.getFiles()[i].getKey().length());
    			}
    			
    			int offset;
    			int j;
    			if(!path.equals("")){
    				folders = new String[objects.getFolders().length + 1];
    				offset = 1;
    				j = offset;
    				folders[0] = "..";
    			} else {
    				folders = new String[objects.getFolders().length];
    				offset = 0;
    				j = offset;
    			}
    			
    			while(j < objects.getFolders().length + offset){
    				folders[j] = objects.getFolders()[j-offset].getKey().substring(0+path.length(),objects.getFolders()[j-offset].getKey().length()-1);
    				j++;
    			}
    		}

    		@Override
    		protected void onPostExecute(Void unused) {
    			if(success){
    				lstFiles.setAdapter(new ArrayAdapter<String>(ctx,R.layout.file_listitem,R.id.litFileText,files));
    				lstFiles.setOnItemClickListener(new OnItemClickListener() {
						@Override
						public void onItemClick(AdapterView<?> arg0, View v, int position, long id) {
							downloadFile(files[(int) id]);
						}
    		        });
    				
    				lstFolders.setAdapter(new ArrayAdapter<String>(ctx,R.layout.folder_listitem,R.id.litFolderText,folders));
    				lstFolders.setOnItemClickListener(new OnItemClickListener() {
						@Override
						public void onItemClick(AdapterView<?> arg0, View v, int position, long id) {
							if(folders[(int) id].equals("..")){
								String[] pathSplit = path.split("/");
								path = "";
								for(int i = 0;i < pathSplit.length - 1; i++){
									path += pathSplit[i] + "/";
								}
							} else {
								path = path + folders[(int) id] + "/";
							}
							loadObjects();
						}
    		        });
    				
    				tvPath.setText("/HOME" + "/" + bucket + path);
    			} else {
    				tvPath.setText("Error: " + error);
    			}
    			pdlg.dismiss();
    		}
    	}
    	
    	new ObjectLoader().execute();
    }
	
	private void downloadFile(String f){
    	if(!refreshGsd()){ return; } 
    	
    	file = f;
    	
    	pdlg = ProgressDialog.show(this,"", "Downloading " + file + "...", true); 
    	pdlg.show();
    	
    	class FileDownloader extends AsyncTask<Void, String, Void> {
    		
    		private boolean success;
    		private String error;
    		
    		@Override
    		protected Void doInBackground(Void... unused) {
	    		try {
	    			InputStream data = gsd.downloadGsFile(bucket, "/" +path+file);
	    			LocalDataAdapter lda = new LocalDataAdapter();
					lda.writeFile(file, settings.getString("gsDownloadDir", ""), data);
	    			success = true;
	    		} catch (BotStorageException e) {
	    			success = false;
	    			gsd = null;
	    			error = e.getMessage();
				} catch (IOException e) {
	    			success = false;
	    			gsd = null;
	    			error = e.getMessage();
				}
    			return(null);
    		}
    		
    		@Override
    		protected void onPostExecute(Void unused) {
    			if(!success){
    				tvPath.setText("Error: " + error);
    			}
    			pdlg.dismiss();
    		}
    	}
    	
    	new FileDownloader().execute();
    }

	// MENU
	/* Creates the menu items */
	public boolean onCreateOptionsMenu(Menu menu) {
		menu.add(0, MENU_RELOAD, 0, "Refresh");
		menu.add(0, MENU_BUCKETS, 0, "Buckets");
		return true;
	}

	/* Handles item selections */
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case MENU_RELOAD:
			loadObjects();
			return true;
		case MENU_BUCKETS:
			this.finish();
			return true;
		}
		return false;
	}
}